﻿Imports System
Imports System.Web
Imports System.Net
Imports System.IO
Imports NEvoWeb.Modules.NB_Store.SharedFunctions
Imports System.Collections.Specialized

Namespace NEvoWeb.Modules.NB_Store.Gateway

    Public Class GatewayCyberPlus
        Inherits GatewayInterface

        Private Const GATEWAYSETTING As String = "cyberplus.gateway"
        Private Const BUTTONNAME As String = "cyberplusbutton"

        Public Overrides Function GetButtonHtml(ByVal PortalID As Integer, ByVal OrderID As Integer, ByVal Lang As String) As String
            Dim strHTML As String = ""
            Dim strSettingXML As String = GetStoreSetting(PortalID, GATEWAYSETTING, Lang)
            'get the gateway settings from the NB_Store settings table
            If strSettingXML <> "" Then
                'Move the xml format settings into the a hashtable so we can use it easily.
                Dim setParams As Hashtable = createSettingsTable(strSettingXML)
                'Build Html to display the payment button.
                strHTML = "<input type=""image"" name=""" & BUTTONNAME & """ border=""0"" src=""" & setParams("ButtonImageURL") & """/>"
            Else
                strHTML = "<h1>Error: NO SETTINGS</h1><br/>Setting ""cyberplus.gateway"" is missing or empty."
            End If
            Return strHTML
        End Function

        Public Overrides Sub AutoResponse(ByVal PortalID As Integer, ByVal Request As System.Web.HttpRequest)
            Dim objSCtrl As New SettingsController
            Dim objOCtrl As New OrderController
            Dim objPCtrl As New ProductController
            Dim objOInfo As NB_Store_OrdersInfo
            ' ------------------------------------------------------------------------
            ' In this case the payment provider passes back data via form POST.
            ' Get the data we need.
            Dim StatusCode As String = Request.Form("vads_result")
            Dim StoreOrderID As Integer = CInt(Request.Form("vads_order_id"))
            Dim CartID As String = Request.Form("vads_order_info2")
            Dim ClientLang As String = Request.Form("vads_order_info")

            UpdateLog("AUTO: " & StoreOrderID & " Status : " & StatusCode)

            'clear cart parameters, this is not strictly needed but does help tidy things up.
            Dim objCCtrl As New CartController
            Dim objCInfo As NB_Store_CartInfo = objCCtrl.GetCart(CartID)
            If Not objCInfo Is Nothing Then
                objCInfo.BankTransID = -1
                objCInfo.BankHtmlRedirect = ""
                objCCtrl.UpdateObjCart(objCInfo)
            End If

            If Request.Form("signature") = getSignature(getSignatureReturnData(PortalID, ClientLang, Request)) Then
                ' This section updates the order.
                objOInfo = objOCtrl.GetOrder(StoreOrderID)
                If Not objOInfo Is Nothing Then
                    'check that the order is valid. (Not
                    If Request.Form("vads_result") = "00" Then
                        If Not objOInfo.OrderIsPlaced Then
                            'remove qty in trans
                            objPCtrl.UpdateStockLevel(objOInfo.OrderID)
                            'set order status to Payed
                            objOInfo.OrderStatusID = 40
                            Dim UsrID As Integer = objOInfo.UserID
                            If UsrID = -1 Then UsrID = 0
                            objOInfo.OrderNumber = Format(PortalID, "00") & "-" & UsrID.ToString("0000#") & "-" & objOInfo.OrderID.ToString("0000#") & "-" & objOInfo.OrderDate.ToString("yyyyMMdd")
                            objOInfo.OrderIsPlaced = True
                            objOCtrl.UpdateObjOrder(objOInfo)
                            'Send email confirmation
                            SendEmailToClient(PortalID, GetClientEmail(PortalID, objOInfo), objOInfo.OrderNumber, objOInfo, "paymentOK.email", ClientLang)
                            SendEmailToManager(PortalID, objOInfo.OrderNumber, objOInfo, "paymentOK.email")
                        End If
                    Else
                        'check if order has already been cancelled
                        If Not objOInfo.OrderStatusID = 30 Then
                            'remove qty in trans
                            objPCtrl.RemoveModelQtyTrans(objOInfo.OrderID)
                            'set order status to cancelled
                            objOInfo.OrderStatusID = 30
                            objOCtrl.UpdateObjOrder(objOInfo)
                        End If
                    End If
                End If
            End If
        End Sub

        Public Overrides Function GetCompletedHtml(ByVal PortalID As Integer, ByVal UserID As Integer, ByVal Request As System.Web.HttpRequest) As String
            Dim objSCtrl As New SettingsController
            Dim objOCtrl As New OrderController
            Dim objPCtrl As New ProductController
            Dim objOInfo As NB_Store_OrdersInfo
            Dim objSInfo As NB_Store_SettingsTextInfo
            Dim ordID As Integer = -1
            Dim rtnMsg As String = ""
            'Get the order id back from the url.
            ordID = CInt(Request.Form("vads_order_id"))
            Dim StatusCode As String = Request.Form("vads_result")
            Dim ClientLang As String = Request.Form("vads_order_info")

            'set rtnMsg to security warning message.
            objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentSECURITY.text", GetCurrentCulture)
            rtnMsg = objSInfo.SettingText

            UpdateLog("COMPLETED: " & ordID & " Status : " & StatusCode)

            If Request.Form("signature") = getSignature(getSignatureReturnData(PortalID, ClientLang, Request)) Then
                If IsNumeric(ordID) Then
                    objOInfo = objOCtrl.GetOrder(ordID)
                    If Not objOInfo Is Nothing Then
                        'Here we make sure that the user trying to view the order is the same as the user that placed the order.
                        'If this is not the case, then we want to display the security warning.
                        If objOInfo.UserID = UserID Then

                            If Request.Form("vads_result") = "00" Then
                                ' check if order has already been processed
                                If Not objOInfo.OrderIsPlaced Then
                                    'remove qty in trans
                                    objPCtrl.UpdateStockLevel(objOInfo.OrderID)
                                    'set order status to Payed
                                    objOInfo.OrderStatusID = 45
                                    objOInfo.OrderNumber = Format(PortalID, "00") & "-" & UserID.ToString("0000#") & "-" & objOInfo.OrderID.ToString("0000#") & "-" & objOInfo.OrderDate.ToString("yyyyMMdd")
                                    objOInfo.OrderIsPlaced = True
                                    objOCtrl.UpdateObjOrder(objOInfo)
                                    'because in this case the order should have been processed by the autoresponse, but has not.
                                    'We're therefore going to send a payment unverified email to the client and manager.
                                    'This just tells the manager to check the payment has actually gone through.
                                    SendEmailToManager(PortalID, objOInfo.OrderNumber, objOInfo, "paymentunverified.email")
                                End If
                                'set completed order message
                                objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentOK.text", GetCurrentCulture)
                                rtnMsg = objSInfo.SettingText
                            Else
                                ' check if order has already been processed
                                If Not objOInfo.OrderIsPlaced Then
                                    'check if order has already been cancelled
                                    If Not objOInfo.OrderStatusID = 30 Then
                                        'remove qty in trans
                                        objPCtrl.RemoveModelQtyTrans(objOInfo.OrderID)
                                        'set order status to cancelled
                                        objOInfo.OrderStatusID = 30
                                        objOCtrl.UpdateObjOrder(objOInfo)
                                    End If
                                    'set Cancel order message
                                    objSInfo = objSCtrl.GetSettingsText(PortalID, "paymentFAIL.text", GetCurrentCulture)
                                    rtnMsg = objSInfo.SettingText
                                End If
                            End If

                            'Do Token Replacement
                            Dim objTR As New TokenStoreReplace(objOInfo, GetMerchantCulture(PortalID))
                            rtnMsg = objTR.DoTokenReplace(rtnMsg)
                        End If
                    End If
                End If
            End If

            Return rtnMsg
        End Function

        Public Overrides Function GetBankClick(ByVal PortalID As Integer, ByVal Request As System.Web.HttpRequest) As Boolean
            'test if button has been clicked
            If Not Request.Form.Item(BUTTONNAME & ".x") Is Nothing Then
                Return True
            Else
                Return False
            End If
        End Function

        Public Overrides Sub SetBankRemotePost(ByVal PortalID As Integer, ByVal OrderID As Integer, ByVal Lang As String, ByVal Request As System.Web.HttpRequest)
            Dim strSettingXML As String = GetStoreSetting(PortalID, GATEWAYSETTING, Lang)
            If strSettingXML <> "" Then
                Dim RPost As New RemotePost ' RemotePost class from NB_Store, this generates the re-direct html required.
                Dim xmlDoc As New Xml.XmlDataDocument
                Dim xmlNod As Xml.XmlNode
                Dim xmlNodList As Xml.XmlNodeList
                Dim setParams As Hashtable = createSettingsTable(strSettingXML)
                Dim objOCtrl As New OrderController
                Dim gatewayImg As String = GetStoreSetting(PortalID, "gateway.loadimage", "None")

                Dim oInfo As NB_Store_OrdersInfo = objOCtrl.GetOrder(OrderID)
                If Not oInfo Is Nothing Then

                    RPost = New RemotePost
                    RPost.Url = setParams("paymentURL")

                    'Replace standard gateway token in xml
                    strSettingXML = ReplaceGatewayTokens(strSettingXML, oInfo, Lang)

                    'Create Post Fields.
                    '--------------------------------------------------------
                    xmlDoc.LoadXml(strSettingXML)
                    xmlNodList = xmlDoc.SelectNodes("root/postfields/*")

                    For Each xmlNod In xmlNodList
                        RPost.Add(xmlNod.Name, xmlNod.InnerText)
                    Next
                    '--------------------------------------------------------

                    'Get the cart data from the database.
                    Dim objCInfo As NB_Store_CartInfo = CurrentCart.GetCurrentCart(PortalID)
                    'Build and assign the re-direct html to the cart.
                    objCInfo.BankHtmlRedirect = RPost.GetPostHtml(gatewayImg)
                    'Save this data on the cart.
                    CurrentCart.Save(objCInfo)
                    '-------------------------------------------------
                    'Do a log statement of the html created, so we have a trace of what data has been passed.
                    UpdateLog("SEND:  CyberPlus " & oInfo.OrderID.ToString)
                    UpdateLog(objCInfo.BankHtmlRedirect)
                End If
            End If

        End Sub

        Public Function createSettingsTable(ByVal SettingsParams As String) As Hashtable
            Return ParseGateway(SettingsParams)
        End Function


        Private Function getSignature(ByVal strMacCalc As String) As String
            Dim objCrypt As New System.Security.Cryptography.SHA1CryptoServiceProvider
            Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strMacCalc)
            Dim rtnStr As String = ""
            bytesToHash = objCrypt.ComputeHash(bytesToHash)
            For Each b As Byte In bytesToHash
                rtnStr &= b.ToString("x2")
            Next
            Return rtnStr
        End Function

        Private Function ReplaceGatewayTokens(ByVal strData As String, ByVal oInfo As NB_Store_OrdersInfo, ByVal Lang As String) As String
            Dim rtnData As String = strData

            rtnData = Replace(rtnData, "[TRANSID]", oInfo.OrderID.ToString("000000"))
            rtnData = Replace(rtnData, "[ORDERID]", oInfo.OrderID.ToString)
            rtnData = Replace(rtnData, "[AMOUNT]", Replace(Replace(oInfo.Total.ToString("0.00"), ".", ""), ",", ""))

            rtnData = Replace(rtnData, "[LANG]", Lang)
            rtnData = Replace(rtnData, "[LANGCODE]", Lang.Substring(0, 2))
            rtnData = Replace(rtnData, "[COUNTRYCODE]", Lang.Substring(3, 2))

            rtnData = Replace(rtnData, "[CARTID]", CurrentCart.GetCurrentCart(oInfo.PortalID).CartID)


            rtnData = Replace(rtnData, "[YEAR]", Year(Now).ToString("0000"))
            rtnData = Replace(rtnData, "[MONTH]", Month(Now).ToString("00"))
            rtnData = Replace(rtnData, "[DAY]", Day(Now).ToString("00"))
            rtnData = Replace(rtnData, "[HOUR]", Hour(Now).ToString("00"))
            rtnData = Replace(rtnData, "[MINUTE]", Minute(Now).ToString("00"))
            rtnData = Replace(rtnData, "[SECOND]", Second(Now).ToString("00"))

            ' just make sure we don;t remove the signature token when we do the order token replacement
            rtnData = Replace(rtnData, "[SIGNATURE]", "***SIGNATURE***")

            'do standard NB_Store order tokens
            Dim objTR As New TokenStoreReplace(oInfo, GetCurrentCulture)
            rtnData = objTR.DoTokenReplace(rtnData)

            rtnData = Replace(rtnData, "***SIGNATURE***", getSignature(getSignatureSendData(oInfo.PortalID, Lang, rtnData)))

            Return rtnData
        End Function


        Private Function getSignatureSendData(ByVal PortalID As Integer, ByVal Lang As String, ByVal strDataXML As String) As String
            Dim strSettingXML As String = GetStoreSetting(PortalID, GATEWAYSETTING, Lang)
            If strSettingXML <> "" Then
                Dim strMacCalc As String = ""
                Dim strFields() As String
                Dim xmlDoc As New Xml.XmlDataDocument

                xmlDoc.LoadXml(strDataXML)

                'get fields required.
                Dim setParams As Hashtable = createSettingsTable(strSettingXML)
                strFields = setParams("signature_fields").ToString.Split(","c)
                For lp As Integer = 0 To strFields.GetUpperBound(0)
                    If Not xmlDoc.SelectSingleNode("root/postfields/" & strFields(lp)) Is Nothing Then
                        strMacCalc &= xmlDoc.SelectSingleNode("root/postfields/" & strFields(lp)).InnerText & "+"
                    End If
                Next
                strMacCalc &= setParams("certificate").ToString

                Return strMacCalc
            Else
                Return ""
            End If
        End Function


        Private Function getSignatureReturnData(ByVal PortalID As Integer, ByVal Lang As String, ByVal htRequest As HttpRequest) As String
            Dim strSettingXML As String = GetStoreSetting(PortalID, GATEWAYSETTING, Lang)
            If strSettingXML <> "" Then
                Dim strMacCalc As String = ""
                Dim setParams As Hashtable = createSettingsTable(strSettingXML)
                Dim rtnFields As New Hashtable

                'get return field into hastable
                For Each strKey As String In htRequest.Form.Keys
                    If strKey.ToLower.StartsWith("vads_") Then
                        rtnFields.Add(strKey, htRequest.Form(strKey))
                    End If
                Next

                'sort into key order
                Dim keys As ICollection = rtnFields.Keys
                Dim keysArray(rtnFields.Count - 1) As String
                keys.CopyTo(keysArray, 0)
                Array.Sort(keysArray)
                For Each key As String In keysArray
                    If key.ToLower.StartsWith("vads_") Then
                        strMacCalc &= htRequest.Form(key) & "+"
                    End If
                Next

                strMacCalc &= setParams("certificate").ToString

                Return strMacCalc
            Else
                Return ""
            End If
        End Function

    End Class
End Namespace
